/*
 * 
 * 
 */
Ext.ns('Ext.ux.grid');

Ext.ux.grid.LockingGridPanel = Ext.extend(Ext.grid.GridPanel, {
			initComponent : function() {

				if (this.cm) {
					Ext.apply(this.cm,Ext.ux.grid.LockingColumnModel.prototype);
					if( this.cm.config[0].id=='checker')
					this.cm.isFirstLock = true;
				
					if (this.sm) {
						this.on('render', function() {var view = this.grid.getView();view.lockedBody.on('mousedown',this.onMouseDown, this);Ext.fly(view.lockedInnerHd).on('mousedown',this.onHdMouseDown, this);}, this.sm);

					}
				} else if (!this.colModel && Ext.isArray(this.columns)) {
					
					this.colModel = new Ext.ux.grid.LockingColumnModel(this.columns);
					if( this.colModel.config[0].id=='checker')
					this.colModel.isFirstLock = true;
					if (this.sm) {
						this.on('render', function() {var view = this.grid.getView();view.lockedBody.on('mousedown',this.onMouseDown, this);Ext.fly(view.lockedInnerHd).on('mousedown',this.onHdMouseDown, this);}, this.sm);

					}
					delete this.columns;
				}

				Ext.ux.grid.LockingGridPanel.superclass.initComponent
						.call(this);
			},
			getView : function() {
				if (!this.view) {
					this.view = new Ext.ux.grid.LockingGridView(this.viewConfig);
				}
				return this.view;
			}

		});

Ext.ux.grid.LockingGridView = Ext.extend(Ext.grid.GridView, {
	lockText : '锁定列',
	unlockText : '解锁列',
	rowBorderWidth : 1,
	lockedBorderWidth : 1,
	/*
	 * This option ensures that height between the rows is synchronized between
	 * the locked and unlocked sides. This option only needs to be used when the
	 * row heights isn't predictable.
	 */
	syncHeights : false,
	
	initTemplates : function() {
		var ts = this.templates || {};
		if (!ts.master) {
			ts.master = new Ext.Template(
					'<div class="x-grid3" hidefocus="true">',
					'<div class="x-grid3-locked">',
					'<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{lstyle}">{lockedHeader}</div></div><div class="x-clear"></div></div>',
					'<div class="x-grid3-scroller"><div class="x-grid3-body" style="{lstyle}">{lockedBody}</div><div class="x-grid3-scroll-spacer"></div></div>',
					'</div>',
					'<div class="x-grid3-viewport x-grid3-unlocked">',
					'<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{ostyle}">{header}</div></div><div class="x-clear"></div></div>',
					'<div class="x-grid3-scroller"><div class="x-grid3-body" style="{bstyle}">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
					'</div>',
					'<div class="x-grid3-resize-marker">&#160;</div>',
					'<div class="x-grid3-resize-proxy">&#160;</div>', '</div>');
		}
		this.templates = ts;
		Ext.ux.grid.LockingGridView.superclass.initTemplates.call(this);
	},
	getEditorParent : function(ed) {
		return this.el.dom;
	},
	initElements : function() {
		var E = Ext.Element;
		var el = this.grid.getGridEl().dom.firstChild;
		var cs = el.childNodes;
		this.el = new E(el);
		this.lockedWrap = new E(cs[0]);
		this.lockedHd = new E(this.lockedWrap.dom.firstChild);
		this.lockedInnerHd = this.lockedHd.dom.firstChild;
		this.lockedScroller = new E(this.lockedWrap.dom.childNodes[1]);
		this.lockedBody = new E(this.lockedScroller.dom.firstChild);
		this.mainWrap = new E(cs[1]);

		this.mainHd = new E(this.mainWrap.dom.firstChild);

		if (this.grid.hideHeaders) {
			this.lockedHd.setDisplayed(false);
			this.mainHd.setDisplayed(false);
		}
		this.innerHd = this.mainHd.dom.firstChild;
		this.scroller = new E(this.mainWrap.dom.childNodes[1]);
		if (this.forceFit) {
			this.scroller.setStyle('overflow-x', 'hidden');
		}
		this.mainBody = new E(this.scroller.dom.firstChild);
		this.focusEl = new E(this.scroller.dom.childNodes[1]);
		this.focusEl.swallowEvent('click', true);
		this.resizeMarker = new E(cs[2]);
		this.resizeProxy = new E(cs[3]);
	},
	destroy:function(){
		 Ext.destroy(
                this.lockedBody,
                this.lockedScroller,
                this.lockedInnerHd,
                this.lockedHd,
                this.lockedWrap
            );
				delete this.lockedWrap;
                delete this.lockedHd;
                delete this.lockedInnerHd;
                delete this.lockedScroller;
                delete this.lockedBody;
      Ext.ux.grid.LockingGridView.superclass.destroy.call(this);

	},
	getLockedRows : function() {
		return this.hasRows() ? this.lockedBody.dom.childNodes : [];
	},

	getLockedRow : function(row) {
		return this.getLockedRows()[row];
	},

	getCell : function(row, col) {
		var llen = this.cm.getLockedCount();
		if (col < llen) {
			return this.getLockedRow(row).getElementsByTagName('td')[col];
		}
		return Ext.ux.grid.LockingGridView.superclass.getCell.call(this, row,
				col - llen);
	},

	getHeaderCell : function(index) {
		var llen = this.cm.getLockedCount();
		if (index < llen) {
			return this.lockedHd.dom.getElementsByTagName('td')[index];
		}
		return Ext.ux.grid.LockingGridView.superclass.getHeaderCell.call(this,
				index - llen);
	},

	addRowClass : function(row, cls) {
		var r = this.getLockedRow(row);
		if (r) {
			this.fly(r).addClass(cls);
		}
		Ext.ux.grid.LockingGridView.superclass.addRowClass.call(this, row, cls);
	},

	removeRowClass : function(row, cls) {
		var r = this.getLockedRow(row);
		if (r) {
			this.fly(r).removeClass(cls);
		}
		Ext.ux.grid.LockingGridView.superclass.removeRowClass.call(this, row,
				cls);
	},

	removeRow : function(row) {
		Ext.removeNode(this.getLockedRow(row));
		Ext.ux.grid.LockingGridView.superclass.removeRow.call(this, row);
	},

	removeRows : function(firstRow, lastRow) {
		var bd = this.lockedBody.dom;
		for (var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++) {
			Ext.removeNode(bd.childNodes[firstRow]);
		}
		Ext.ux.grid.LockingGridView.superclass.removeRows.call(this, firstRow,
				lastRow);
	},

	syncScroll : function(e) {
		var mb = this.scroller.dom;
		this.lockedScroller.dom.scrollTop = mb.scrollTop;
		Ext.ux.grid.LockingGridView.superclass.syncScroll.call(this, e);
	},

	updateSortIcon : function(col, dir) {
		var sc = this.sortClasses, lhds = this.lockedHd.select('td')
				.removeClass(sc), hds = this.mainHd.select('td')
				.removeClass(sc), llen = this.cm.getLockedCount(), cls = sc[dir == 'DESC'
				? 1
				: 0];
		if (col < llen) {
			lhds.item(col).addClass(cls);
		} else {
			hds.item(col - llen).addClass(cls);
		}
	},

	updateAllColumnWidths : function() {
		var tw = this.getTotalWidth(), clen = this.cm.getColumnCount(), lw = this
				.getLockedWidth(), llen = this.cm.getLockedCount(), ws = [], len, i;
		this.updateLockedWidth();
		for (i = 0; i < clen; i++) {
			ws[i] = this.getColumnWidth(i);
			var hd = this.getHeaderCell(i);
			hd.style.width = ws[i];
		}
		var lns = this.getLockedRows(), ns = this.getRows(), row, trow, j;
		for (i = 0, len = ns.length; i < len; i++) {
			row = lns[i];
			row.style.width = lw;
			if (row.firstChild) {
				row.firstChild.style.width = lw;
				trow = row.firstChild.rows[0];
				for (j = 0; j < llen; j++) {
					trow.childNodes[j].style.width = ws[j];
				}
			}
			row = ns[i];
			row.style.width = tw;
			if (row.firstChild) {
				row.firstChild.style.width = tw;
				trow = row.firstChild.rows[0];
				for (j = llen; j < clen; j++) {
					trow.childNodes[j - llen].style.width = ws[j];
				}
			}
		}
		this.onAllColumnWidthsUpdated(ws, tw);
		this.syncHeaderHeight();
	},

	updateColumnWidth : function(col, width) {
		var w = this.getColumnWidth(col), llen = this.cm.getLockedCount(), ns, rw, c, row;
		this.updateLockedWidth();
		if (col < llen) {
			ns = this.getLockedRows();
			rw = this.getLockedWidth();
			c = col;
		} else {
			ns = this.getRows();
			rw = this.getTotalWidth();
			c = col - llen;
		}
		var hd = this.getHeaderCell(col);
		hd.style.width = w;
		for (var i = 0, len = ns.length; i < len; i++) {
			row = ns[i];
			row.style.width = rw;
			if (row.firstChild) {
				row.firstChild.style.width = rw;
				row.firstChild.rows[0].childNodes[c].style.width = w;
			}
		}
		this.onColumnWidthUpdated(col, w, this.getTotalWidth());
		this.syncHeaderHeight();
	},

	updateColumnHidden : function(col, hidden) {
		var llen = this.cm.getLockedCount(), ns, rw, c, row, display = hidden
				? 'none'
				: '';
		this.updateLockedWidth();
		if (col < llen) {
			ns = this.getLockedRows();
			rw = this.getLockedWidth();
			c = col;
		} else {
			ns = this.getRows();
			rw = this.getTotalWidth();
			c = col - llen;
		}
		var hd = this.getHeaderCell(col);
		hd.style.display = display;
		for (var i = 0, len = ns.length; i < len; i++) {
			row = ns[i];
			row.style.width = rw;
			if (row.firstChild) {
				row.firstChild.style.width = rw;
				row.firstChild.rows[0].childNodes[c].style.display = display;
			}
		}
		this.onColumnHiddenUpdated(col, hidden, this.getTotalWidth());
		delete this.lastViewWidth;
		this.layout();
	},

	doRender : function(cs, rs, ds, startRow, colCount, stripe) {
		var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount - 1, tstyle = 'width:'
				+ this.getTotalWidth() + ';', lstyle = 'width:'
				+ this.getLockedWidth() + ';', buf = [], lbuf = [], cb, lcb, c, p = {}, rp = {}, r;
		for (var j = 0, len = rs.length; j < len; j++) {
			r = rs[j];
			cb = [];
			lcb = [];
			var rowIndex = (j + startRow);
			for (var i = 0; i < colCount; i++) {
				c = cs[i];
				p.id = c.id;
				p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last
						? 'x-grid3-cell-last '
						: ''))
						+ (this.cm.config[i].cellCls ? ' '
								+ this.cm.config[i].cellCls : '');
				p.attr = p.cellAttr = '';
				p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
				p.style = c.style;
				if (Ext.isEmpty(p.value)) {
					p.value = '&#160;';
				}
				if (this.markDirty && r.dirty
						&& Ext.isDefined(r.modified[c.name])) {
					p.css += ' x-grid3-dirty-cell';
				}
				if (c.locked) {
					lcb[lcb.length] = ct.apply(p);
				} else {
					cb[cb.length] = ct.apply(p);
				}
			}
			var alt = [];
			if (stripe && ((rowIndex + 1) % 2 === 0)) {
				alt[0] = 'x-grid3-row-alt';
			}
			if (r.dirty) {
				alt[1] = ' x-grid3-dirty-row';
			}
			rp.cols = colCount;
			if (this.getRowClass) {
				alt[2] = this.getRowClass(r, rowIndex, rp, ds);
			}
			rp.alt = alt.join(' ');
			rp.cells = cb.join('');
			rp.tstyle = tstyle;
			buf[buf.length] = rt.apply(rp);
			rp.cells = lcb.join('');
			rp.tstyle = lstyle;
			lbuf[lbuf.length] = rt.apply(rp);
		}
		return [buf.join(''), lbuf.join('')];
	},
	processRows : function(startRow, skipStripe) {
		if (!this.ds || this.ds.getCount() < 1) {
			return;
		}
		var rows = this.getRows(), lrows = this.getLockedRows(), row, lrow;
		skipStripe = skipStripe || !this.grid.stripeRows;
		startRow = startRow || 0;
		for (var i = 0, len = rows.length; i < len; ++i) {
			row = rows[i];
			lrow = lrows[i];
			row.rowIndex = i;
			lrow.rowIndex = i;
			if (!skipStripe) {
				row.className = row.className.replace(this.rowClsRe, ' ');
				lrow.className = lrow.className.replace(this.rowClsRe, ' ');
				if ((idx + 1) % 2 === 0) {
					row.className += ' x-grid3-row-alt';
					lrow.className += ' x-grid3-row-alt';
				}
			}
			if (this.syncHeights) {
				var el1 = Ext.get(row), el2 = Ext.get(lrow), h1 = el1
						.getHeight(), h2 = el2.getHeight();

				if (h1 > h2) {
					el2.setHeight(h1);
				} else if (h2 > h1) {
					el1.setHeight(h2);
				}
			}
		}
		if (startRow === 0) {
			Ext.fly(rows[0]).addClass(this.firstRowCls);
			Ext.fly(lrows[0]).addClass(this.firstRowCls);
		}
		Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls);
		Ext.fly(lrows[lrows.length - 1]).addClass(this.lastRowCls);
	},

	afterRender : function() {
		if (!this.ds || !this.cm) {
			return;
		}
		var bd = this.renderRows() || ['&#160;', '&#160;'];
		this.mainBody.dom.innerHTML = bd[0];
		this.lockedBody.dom.innerHTML = bd[1];
		this.processRows(0, true);
		if (this.deferEmptyText !== true) {
			this.applyEmptyText();
		}
	},

	renderUI : function() {
		var header = this.renderHeaders();
		var body = this.templates.body.apply({
					rows : '&#160;'
				});
		var html = this.templates.master.apply({
					body : body,
					header : header[0],
					ostyle : 'width:' + this.getOffsetWidth() + ';',
					bstyle : 'width:' + this.getTotalWidth() + ';',
					lockedBody : body,
					lockedHeader : header[1],
					lstyle : 'width:' + this.getLockedWidth() + ';'
				});
		var g = this.grid;
		g.getGridEl().dom.innerHTML = html;
		this.initElements();
		Ext.fly(this.innerHd).on('click', this.handleHdDown, this);
		Ext.fly(this.lockedInnerHd).on('click', this.handleHdDown, this);
		this.mainHd.on({
					scope : this,
					mouseover : this.handleHdOver,
					mouseout : this.handleHdOut,
					mousemove : this.handleHdMove
				});
		this.lockedHd.on({
					scope : this,
					mouseover : this.handleHdOver,
					mouseout : this.handleHdOut,
					mousemove : this.handleHdMove
				});
		this.scroller.on('scroll', this.syncScroll, this);
		if (g.enableColumnResize !== false) {
			this.splitZone = new Ext.grid.GridView.SplitDragZone(g,
					this.mainHd.dom);
			this.splitZone.setOuterHandleElId(Ext.id(this.lockedHd.dom));
			this.splitZone.setOuterHandleElId(Ext.id(this.mainHd.dom));
		}
		if (g.enableColumnMove) {
			this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g,
					this.innerHd);
			this.columnDrag.setOuterHandleElId(Ext.id(this.lockedInnerHd));
			this.columnDrag.setOuterHandleElId(Ext.id(this.innerHd));
			this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);
		}
		if (g.enableHdMenu !== false) {
			this.hmenu = new Ext.menu.Menu({
						id : g.id + '-hctx'
					});
			this.hmenu.add({
						itemId : 'asc',
						text : this.sortAscText,
						cls : 'xg-hmenu-sort-asc'
					}, {
						itemId : 'desc',
						text : this.sortDescText,
						cls : 'xg-hmenu-sort-desc'
					});
			if (this.grid.enableColLock !== false) {
				this.hmenu.add('-', {
							itemId : 'lock',
							text : this.lockText,
							cls : 'xg-hmenu-lock'
						}, {
							itemId : 'unlock',
							text : this.unlockText,
							cls : 'xg-hmenu-unlock'
						});
			}
			if (g.enableColumnHide !== false) {
				this.colMenu = new Ext.menu.Menu({
							id : g.id + '-hcols-menu'
						});
				this.colMenu.on({
							scope : this,
							beforeshow : this.beforeColMenuShow,
							itemclick : this.handleHdMenuClick
						});
				this.hmenu.add('-', {
							itemId : 'columns',
							hideOnClick : false,
							text : this.columnsText,
							menu : this.colMenu,
							iconCls : 'x-cols-icon'
						});
			}
			this.hmenu.on('itemclick', this.handleHdMenuClick, this);
		}
		if (g.trackMouseOver) {
			this.mainBody.on({
						scope : this,
						mouseover : this.onRowOver,
						mouseout : this.onRowOut
					});
			this.lockedBody.on({
						scope : this,
						mouseover : this.onRowOver,
						mouseout : this.onRowOut
					});
		}

		if (g.enableDragDrop || g.enableDrag) {
			this.dragZone = new Ext.grid.GridDragZone(g, {
						ddGroup : g.ddGroup || 'GridDD'
					});
		}
		this.updateHeaderSortState();
	},

	layout : function() {
		if (!this.mainBody) {
			return;
		}
		var g = this.grid;
		var c = g.getGridEl();
		var csize = c.getSize(true);
		var vw = csize.width;
		if (!g.hideHeaders && (vw < 20 || csize.height < 20)) {
			return;
		}
		this.syncHeaderHeight();
		if (g.autoHeight) {
			this.scroller.dom.style.overflow = 'visible';
			this.lockedScroller.dom.style.overflow = 'visible';
			if (Ext.isWebKit) {
				this.scroller.dom.style.position = 'static';
				this.lockedScroller.dom.style.position = 'static';
			}
		} else {
			this.el.setSize(csize.width, csize.height);
			var hdHeight = this.mainHd.getHeight();
			var vh = csize.height - (hdHeight);
		}
		this.updateLockedWidth();
		if (this.forceFit) {
			if (this.lastViewWidth != vw) {
				this.fitColumns(false, false);
				this.lastViewWidth = vw;
			}
		} else {
			this.autoExpand();
			this.syncHeaderScroll();
		}
		this.onLayout(vw, vh);
	},

	getOffsetWidth : function() {
		return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth() + this
				.getScrollOffset())
				+ 'px';
	},

	renderHeaders : function() {
		var cm = this.cm, ts = this.templates, ct = ts.hcell, cb = [], lcb = [], p = {}, len = cm
				.getColumnCount(), last = len - 1;
		for (var i = 0; i < len; i++) {
			p.id = cm.getColumnId(i);
			p.value = cm.getColumnHeader(i) || '';
			p.style = this.getColumnStyle(i, true);
			p.tooltip = this.getColumnTooltip(i);
			p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last
					? 'x-grid3-cell-last '
					: ''))
					+ (cm.config[i].headerCls
							? ' ' + cm.config[i].headerCls
							: '');
			if (cm.config[i].align == 'right') {
				p.istyle = 'padding-right:16px';
			} else {
				delete p.istyle;
			}
			if (cm.isLocked(i)) {
				lcb[lcb.length] = ct.apply(p);
			} else {
				cb[cb.length] = ct.apply(p);
			}
		}
		return [ts.header.apply({
							cells : cb.join(''),
							tstyle : 'width:' + this.getTotalWidth() + ';'
						}), ts.header.apply({
							cells : lcb.join(''),
							tstyle : 'width:' + this.getLockedWidth() + ';'
						})];
	},

	updateHeaders : function() {
		var hd = this.renderHeaders();
		this.innerHd.firstChild.innerHTML = hd[0];
		this.innerHd.firstChild.style.width = this.getOffsetWidth();
		this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth();
		this.lockedInnerHd.firstChild.innerHTML = hd[1];
		var lw = this.getLockedWidth();
		this.lockedInnerHd.firstChild.style.width = lw;
		this.lockedInnerHd.firstChild.firstChild.style.width = lw;
	},

	getResolvedXY : function(resolved) {
		if (!resolved) {
			return null;
		}
		var c = resolved.cell, r = resolved.row;
		return c ? Ext.fly(c).getXY() : [this.scroller.getX(),
				Ext.fly(r).getY()];
	},

	syncFocusEl : function(row, col, hscroll) {
		Ext.ux.grid.LockingGridView.superclass.syncFocusEl.call(this, row, col,
				col < this.cm.getLockedCount() ? false : hscroll);
	},

	ensureVisible : function(row, col, hscroll) {
		return Ext.ux.grid.LockingGridView.superclass.ensureVisible.call(this,
				row, col, col < this.cm.getLockedCount() ? false : hscroll);
	},

	insertRows : function(dm, firstRow, lastRow, isUpdate) {
		var last = dm.getCount() - 1;
		if (!isUpdate && firstRow === 0 && lastRow >= last) {
			this.refresh();
		} else {
			if (!isUpdate) {
				this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
			}
			var html = this.renderRows(firstRow, lastRow), before = this
					.getRow(firstRow);
			if (before) {
				if (firstRow === 0) {
					this.removeRowClass(0, this.firstRowCls);
				}
				Ext.DomHelper.insertHtml('beforeBegin', before, html[0]);
				before = this.getLockedRow(firstRow);
				Ext.DomHelper.insertHtml('beforeBegin', before, html[1]);
			} else {
				this.removeRowClass(last - 1, this.lastRowCls);
				Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom,
						html[0]);
				Ext.DomHelper.insertHtml('beforeEnd', this.lockedBody.dom,
						html[1]);
			}
			if (!isUpdate) {
				this.fireEvent('rowsinserted', this, firstRow, lastRow);
				this.processRows(firstRow);
			} else if (firstRow === 0 || firstRow >= last) {
				this.addRowClass(firstRow, firstRow === 0
								? this.firstRowCls
								: this.lastRowCls);
			}
		}
		this.syncFocusEl(firstRow);
	},

	getColumnStyle : function(col, isHeader) {
		var style = !isHeader
				? this.cm.config[col].cellStyle || this.cm.config[col].css
						|| ''
				: this.cm.config[col].headerStyle || '';
		style += 'width:' + this.getColumnWidth(col) + ';';
		if (this.cm.isHidden(col)) {
			style += 'display:none;';
		}
		var align = this.cm.config[col].align;
		if (align) {
			style += 'text-align:' + align + ';';
		}
		return style;
	},

	getLockedWidth : function() {
		return this.cm.getTotalLockedWidth() + 'px';
	},

	getTotalWidth : function() {
		return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth()) + 'px';
	},

	getColumnData : function() {
		var cs = [], cm = this.cm, colCount = cm.getColumnCount();
		for (var i = 0; i < colCount; i++) {
			var name = cm.getDataIndex(i);
			cs[i] = {
				name : (!Ext.isDefined(name)
						? this.ds.fields.get(i).name
						: name),
				renderer : cm.getRenderer(i),
				id : cm.getColumnId(i),
				style : this.getColumnStyle(i),
				locked : cm.isLocked(i)
			};
		}
		return cs;
	},

	renderBody : function() {
		var markup = this.renderRows() || ['&#160;', '&#160;'];
		return [this.templates.body.apply({
							rows : markup[0]
						}), this.templates.body.apply({
							rows : markup[1]
						})];
	},

	refreshRow : function(record) {
		Ext.ux.grid.LockingGridView.superclass.refreshRow.call(this, record);
		var index = Ext.isNumber(record) ? record : this.ds.indexOf(record);
		this.getLockedRow(index).rowIndex = index;
	},

	refresh : function(headersToo) {
		this.fireEvent('beforerefresh', this);
		this.grid.stopEditing(true);
		var result = this.renderBody();
		this.mainBody.update(result[0]).setWidth(this.getTotalWidth());
		this.lockedBody.update(result[1]).setWidth(this.getLockedWidth());
		if (headersToo === true) {
			this.updateHeaders();
			this.updateHeaderSortState();
		}
		this.processRows(0, true);
		this.layout();
		this.applyEmptyText();
		this.fireEvent('refresh', this);
	},

	onDenyColumnLock : function() {

	},

	initData : function(ds, cm) {
		if (this.cm) {
			this.cm.un('columnlockchange', this.onColumnLock, this);
		}
		Ext.ux.grid.LockingGridView.superclass.initData.call(this, ds, cm);
		if (this.cm) {
			this.cm.on('columnlockchange', this.onColumnLock, this);
		}
	},

	onColumnLock : function() {
		this.refresh(true);
	},

	handleHdMenuClick : function(item) {
		var index = this.hdCtxIndex, cm = this.cm, id = item.getItemId(), llen = cm
				.getLockedCount();
		switch (id) {
			case 'lock' :
				if (cm.getColumnCount(true) <= llen + 1) {
					this.onDenyColumnLock();
					return;
				}
				if (llen != index) {
					cm.setLocked(index, true, true);
					cm.moveColumn(index, llen);
					this.grid.fireEvent('columnmove', index, llen);
				} else {
					cm.setLocked(index, true);
				}
				break;
			case 'unlock' :
				if (llen - 1 != index) {
					cm.setLocked(index, false, true);
					cm.moveColumn(index, llen - 1);
					this.grid.fireEvent('columnmove', index, llen - 1);
				} else {
					cm.setLocked(index, false);
				}
				break;
			default :
				return Ext.ux.grid.LockingGridView.superclass.handleHdMenuClick
						.call(this, item);
		}
		return true;
	},

	handleHdDown : function(e, t) {
		Ext.ux.grid.LockingGridView.superclass.handleHdDown.call(this, e, t);
		if (this.grid.enableColLock !== false) {
			if (Ext.fly(t).hasClass('x-grid3-hd-btn')) {
				var hd = this.findHeaderCell(t), index = this.getCellIndex(hd), ms = this.hmenu.items, cm = this.cm;
				ms.get('lock').setDisabled(cm.isLocked(index));
				ms.get('unlock').setDisabled(!cm.isLocked(index));
			}
		}
	},

	syncHeaderHeight : function() {
	
		this.innerHd.firstChild.firstChild.style.height = 'auto';
		this.lockedInnerHd.firstChild.firstChild.style.height = 'auto';
		var hd = this.innerHd.firstChild.firstChild.offsetHeight, lhd = this.lockedInnerHd.firstChild.firstChild.offsetHeight, height = (lhd > hd
				? lhd
				: hd)
				+ 'px';
		this.innerHd.firstChild.firstChild.style.height = height;
		this.lockedInnerHd.firstChild.firstChild.style.height = height;
	},

	updateLockedWidth : function() {
		var lw = this.cm.getTotalLockedWidth(), tw = this.cm.getTotalWidth()
				- lw, csize = this.grid.getGridEl().getSize(true), lp = Ext.isBorderBox
				? 0
				: this.lockedBorderWidth, rp = Ext.isBorderBox
				? 0
				: this.rowBorderWidth, vw = (csize.width - lw - lp - rp) + 'px', so = this
				.getScrollOffset();
		if (!this.grid.autoHeight) {
			var vh = (csize.height - this.mainHd.getHeight()) + 'px';
			this.lockedScroller.dom.style.height = vh;
			this.scroller.dom.style.height = vh;
		}
		this.lockedWrap.dom.style.width = (lw + rp) + 'px';
		this.scroller.dom.style.width = vw;
		this.mainWrap.dom.style.left = (lw + lp + rp) + 'px';
		if (this.innerHd) {
			this.lockedInnerHd.firstChild.style.width = lw + 'px';
			this.lockedInnerHd.firstChild.firstChild.style.width = lw + 'px';
			this.innerHd.style.width = vw;
			this.innerHd.firstChild.style.width = (tw + rp + so) + 'px';
			this.innerHd.firstChild.firstChild.style.width = tw + 'px';
		}
		if (this.mainBody) {
			this.lockedBody.dom.style.width = (lw + rp) + 'px';
			this.mainBody.dom.style.width = (tw + rp) + 'px';
		}
	}
});

Ext.ux.grid.LockingColumnModel = Ext.extend(Ext.grid.ColumnModel, {
			isLocked : function(colIndex) {

				if (this.isFirstLock && colIndex == 0) {
					return true;
				}
				return this.config[colIndex].locked === true;
			},

			setLocked : function(colIndex, value, suppressEvent) {
				if (this.isLocked(colIndex) == value) {
					return;
				}
				this.config[colIndex].locked = value;
				if (!suppressEvent) {
					this.fireEvent('columnlockchange', this, colIndex, value);
				}
			},

			getTotalLockedWidth : function() {
				var totalWidth = 0;
				for (var i = 0, len = this.config.length; i < len; i++) {
					if (this.isLocked(i) && !this.isHidden(i)) {
						totalWidth += this.getColumnWidth(i);
					}
				}
				return totalWidth;
			},

			getLockedCount : function() {
				for (var i = 0, len = this.config.length; i < len; i++) {
					if (!this.isLocked(i)) {
						return i;
					}
				}
			},

			moveColumn : function(oldIndex, newIndex) {
				if (oldIndex < newIndex && this.isLocked(oldIndex)
						&& !this.isLocked(newIndex)) {
					this.setLocked(oldIndex, false, true);
				} else if (oldIndex > newIndex && !this.isLocked(oldIndex)
						&& this.isLocked(newIndex)) {
					this.setLocked(oldIndex, true, true);
				}
				Ext.ux.grid.LockingColumnModel.superclass.moveColumn.apply(
						this, arguments);
			}
		});
